#-*- coding:utf-8 -*-
import operator
from functools import reduce
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
import numpy as np
import os
import math
import random


class drow_text(object):
    """
    OLED显示文字时，需要的矩阵
    """
    def __init__(self):
        self.word_width=16
        self.word_height=16
        self.font_size=16
        self.word_point_x=0
        self.word_point_y=-4
        self.ttc_path= os.path.join(os.path.dirname(os.path.dirname(__file__)),'src','MSYHL.TTC')
        self.filling_char="0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00"


    def string_reverse(self,string):
        """
        二进制数反转
        :param string: type string
        :return:
        """
        return string[::-1]

    def bin_map_hex(self,bin_str):
        """
        四位二进制数转十六进制数
        :param bin_str: 四位二进制数  type string
        :return:
        """
        number_list = [8, 4, 2, 1]
        hex_list = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
        bin_value = map(lambda x: number_list[x[0]] if x[1] == '1' else 0, enumerate(bin_str))
        value = reduce(operator.add, list(bin_value))
        return hex_list[value]

    def bin2hex(self,bin_str_list):
        """
        二进制数list转十六进制数string
        :param bin_str_list:
        :return:
        """
        rel_list = []
        for sub in bin_str_list:
            rel_list.append([self.string_reverse(sub[4:8]), self.string_reverse(sub[0:4]), self.string_reverse(sub[12:16]),
                             self.string_reverse(sub[8:12])])
        hex_str_list = list(
            map(lambda x: (self.bin_map_hex(x[0]) + self.bin_map_hex(x[1]), self.bin_map_hex(x[2]) + self.bin_map_hex(x[3])), rel_list))
        hex_str_list = list(map(lambda x: "0x" + x[0] + ',0x' + x[1], hex_str_list))
        hex_str = ",".join(hex_str_list)
        return hex_str

    def words_hex(self,word_list,variable_name):
        """
        多行字转成hex十六进制
        :param word_list: 多行字 type []string
        :return:
        """
        values_list=[]
        char_len=32
        for i,sub_row in enumerate(word_list):
            # w, h = font.getsize(sub_row)
            one_row_hex=""
            for sub_word in sub_row:
                if sub_word=='':
                    continue
                image = Image.new("RGB", [self.word_width, self.word_height], color=(255, 255, 255))
                draw = ImageDraw.Draw(image)
                font = ImageFont.truetype(self.ttc_path, self.font_size)
                draw.text((self.word_point_x, self.word_point_y), sub_word, font=font, fill=(0, 0, 0))
                arr = np.asarray(image)
                arr = arr.tolist()
                arr_list = []
                for sub in arr:
                    vale = list(map(lambda x: '0' if (x[0] + x[1] + x[2]) // 3 > 180 else '1', sub))
                    arr_list.append(vale)

                arr_list = list(map(lambda x: ''.join(x), arr_list))
                values = self.bin2hex(arr_list)
                char_len=values.split(',').__len__()
                one_row_hex+='{'+values+'},\n\r'
            char_number=len(sub_row)
            if char_number<8:
                for u in range(8-len(sub_row)):
                    one_row_hex+='{'+self.filling_char+'},\n\r'
                    char_number+=1
            one_row_hex += '};'
            start_row_hex = 'static unsigned char  %s[%s][%s] U8G_PROGMEM={\n\r' %(variable_name,char_number,char_len)
            one_row_hex=start_row_hex+one_row_hex
            values_list.append(one_row_hex)
            # print(one_row_hex)
        return values_list

class oled_show_text(object):
    """
    oled的arduino代码生成
    """
    def __init__(self):
        self.one_row_display="""
        void OLED_display_single(int x,int y)
{ 
     u8g.firstPage();
     do {
        u8g.drawXBMP( x   ,y, 16, 16, suma_single[0]);
        u8g.drawXBMP( x+16,y, 16, 16, suma_single[1]); 
        u8g.drawXBMP( x+2*16,y, 16, 16, suma_single[2]);
        u8g.drawXBMP( x+3*16,y, 16, 16, suma_single[3]);
        u8g.drawXBMP( x+4*16,y, 16, 16, suma_single[4]);
        u8g.drawXBMP( x+5*16,y, 16, 16, suma_single[5]);
        u8g.drawXBMP( x+6*16,y, 16, 16, suma_single[6]);
        u8g.drawXBMP( x+7*16,y, 16, 16, suma_single[7]);
        }
     while ( u8g.nextPage() );
}
        """
        self.one_row_text="""
        u8g.drawXBMP( x   ,y, 16, 16, suma_single[0]);
        u8g.drawXBMP( x+16,y, 16, 16, suma_single[1]); 
        u8g.drawXBMP( x+2*16,y, 16, 16, suma_single[2]);
        u8g.drawXBMP( x+3*16,y, 16, 16, suma_single[3]);
        u8g.drawXBMP( x+4*16,y, 16, 16, suma_single[4]);
        u8g.drawXBMP( x+5*16,y, 16, 16, suma_single[5]);
        u8g.drawXBMP( x+6*16,y, 16, 16, suma_single[6]);
        u8g.drawXBMP( x+7*16,y, 16, 16, suma_single[7]);
        """

    def one_row_show(self,text,x,y):
        """
        单行oled显示的arduino代码
        :param text: 要显示文字 type string
        :param x: 位置的x轴
        :param y: 位置的y轴
        :return: 需要的显示代码
        """
        text_list=[text]
        drow_obj = drow_text()
        variable_name = self.get_random_variable_name()
        word_hex_list=drow_obj.words_hex(text_list,variable_name)
        one_row_hex=word_hex_list[0]
        self.oled_run='OLED_display_{}({},{});'.format('single',x,y)
        one_row_text=""
        for i in range(8):
            one_row_text+="u8g.drawXBMP( x+16*{},y, 16, 16, {}[{}]);\n".format(i,variable_name,i)
        oled_display_list=[one_row_hex,self.one_row_display,self.oled_run,one_row_text]
        return oled_display_list


    def multiple_row_show(self,multiple_text_list=None):
        """
        四行oled显示的arduino代码
        :param multiple_text_list: 四行的文字 type []string
        :return: 需要的显示代码
        """
        drow_obj = drow_text()
        do_code = ''
        defind_code=""
        draw_list=[]
        for i,one_row in enumerate(multiple_text_list):
            variable = self.get_random_variable_name()
            word_hex_list = drow_obj.words_hex([one_row], variable)
            defind_code+='\n\r'.join(word_hex_list)+"\n\r"
            one_draw=""
            for u in range(8):
                one_word="u8g.drawXBMP( x+16*{} ,y+16*{}, 16, 16, {}[{}]);\n\r".format(u,i,variable,u)
                do_code+=one_word
                one_draw+=one_word
            draw_list.append(one_draw)
        do_code="""
void OLED_display_multiple(int x,int y)
{ 
     u8g.firstPage();
     do {
        %s
        }
     while ( u8g.nextPage() );
}
        """ %do_code
        oled_run='OLED_display_{}({},{});'.format('multiple',0,0)

        return [defind_code,do_code,oled_run,draw_list]

    def get_random_variable_name(self):
        """
        随机返回一个变量名字
        :return:
        """
        prefix="variable"
        number=round(math.pow(random.random(), 3) * 100000000)
        return prefix+str(number)













if __name__ == '__main__':
    ll=["你的有效游戏A3"]
    # drow_obj=drow_text()
    # word_hex=drow_obj.words_hex(ll)
    # print(word_hex)
    one=oled_show_text()
    # hex_value=one.multiple_row_show(["你的","号的","哈哈","去你的"])
    print(one.get_random_variable_name())
